package com.zhengxing.jienci.content.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhengxing.jienci.common.constant.RedisKey;
import com.zhengxing.jienci.common.pojo.CustomizePage;
import com.zhengxing.jienci.common.pojo.Information;
import com.zhengxing.jienci.common.pojo.InformationAndUser;
import com.zhengxing.jienci.common.pojo.SysUser;
import com.zhengxing.jienci.common.support.SimpleResponse;
import com.zhengxing.jienci.common.util.CommonUtils;
import com.zhengxing.jienci.common.util.IdGenerateUtil;
import com.zhengxing.jienci.content.mapper.InformationMapper;
import com.zhengxing.jienci.content.service.InformationService;
import com.zhengxing.jienci.feign.UserFeginApi;
import com.zhengxing.jienci.web.context.SecurityContext;

@Service
public class InformationServiceImpl implements InformationService {
	
	@Autowired
	private InformationMapper informationMapper;
	
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	
	@Autowired
	private UserFeginApi userFeginApi;
	
	private final Pattern ATTR_PATTERN = Pattern.compile("<img[^<>]*?\\ssrc=['\"]?(.*?)['\"]?\\s.*?>",Pattern.CASE_INSENSITIVE);

	@Override
	public IPage<Information> list(CustomizePage page, Information information) {
		IPage<Information> pages = new Page<Information>(page.getPageNow(), page.getPageSize());
		List<Information> informationList = informationMapper.list(pages, information);
		informationList.forEach(info -> {
			SysUser sysUser = userFeginApi.getSimpleUserById(info.getApplyUser());
			info.setApplyImage(sysUser.getImage());
			info.setApplyNickName(sysUser.getNickname());
			String commentNumbers = redisTemplate.opsForValue().get(RedisKey.SUM_BACK_OPERATION_PREFIX + info.getId());
			info.setCommentNumbers(commentNumbers == null ? 0 : Long.parseLong(commentNumbers));
		});
		pages.setRecords(informationList);
		return pages;
	}
	
	@Override
	public IPage<Information> listAttention(CustomizePage page) {
		IPage<Information> pages = new Page<Information>(page.getPageNow(), page.getPageSize());
		String userId = SecurityContext.getUserId();
		String key = RedisKey.INFORMATION_ATTENTION_PREFIX + userId;
		int pageStart = (page.getPageNow() - 1) * page.getPageSize();
		int pageEnd = pageStart + page.getPageSize();
		//获取资讯关注列表
		List<String> informationIds = redisTemplate.opsForList().range(key, pageStart, pageEnd);
		List<Information> informations = new ArrayList<Information>();
		if(informationIds != null && informationIds.size() > 0) {
			informations = informationMapper.selectBatchIds(informationIds);
			informations.forEach(info -> {
				SysUser sysUser = userFeginApi.getSimpleUserById(info.getApplyUser());
				info.setApplyImage(sysUser.getImage());
				info.setApplyNickName(sysUser.getNickname());
				String commentNumbers = redisTemplate.opsForValue().get(RedisKey.SUM_BACK_OPERATION_PREFIX + info.getId());
				info.setCommentNumbers(commentNumbers == null ? 0 : Long.parseLong(commentNumbers));
			});
		} 
		pages.setRecords(informations);
		pages.setTotal(redisTemplate.opsForList().size(key));
		return pages;
	};

	@Override
	public IPage<Information> listByUserId(CustomizePage page, Information information) {
		String userId = SecurityContext.getUserId();
		information.setApplyUser(userId);
		return list(page, information);
	}
	
	@Override
	public InformationAndUser queryById(String id) {
		String userId = SecurityContext.getUserId();
		//获取资讯详情
		Information information = informationMapper.selectById(id);
		//获取资讯发布人详情
		SysUser userDetail = userFeginApi.getDetailUserById(information.getApplyUser());
		//判断自己是否已经关注
		Boolean isAttention = redisTemplate.opsForSet().isMember(RedisKey.FOLLOWER_OPERATION_PREFIX + userDetail.getId(), userId);
		userDetail.setAttention(isAttention);
		Long followerNumber = redisTemplate.opsForSet().size(RedisKey.FOLLOWER_OPERATION_PREFIX + userDetail.getId());
		userDetail.setFollowerNumber(followerNumber);
		//设置资讯阅读量
		Long readNumber = redisTemplate.opsForValue().increment(RedisKey.INFORMATION_READ_PREFIX + id);
		information.setReadNumber(readNumber);
		//设置文章是否点赞
		Boolean isGood = redisTemplate.opsForSet().isMember(RedisKey.INFORMATION_IS_GOOD_OPERATION_PRFIX + id, userId);
		information.setGood(isGood);
		//设置点赞量
		Long isGoodNumber = redisTemplate.opsForSet().size(RedisKey.INFORMATION_IS_GOOD_OPERATION_PRFIX + id);
		information.setIsGoodNumber(isGoodNumber);
		return new InformationAndUser(userDetail, information);
	}
	
	@Override
	public SimpleResponse apply(Information information) {
		int result = 0;
		String images = getImageUrlFromText(information.getContent());
		information.setImage(images);
		String userId = SecurityContext.getUserId();
		if(StringUtils.isBlank(information.getId())) {
			information.setId(IdGenerateUtil.getId());
			information.setApplyUser(userId);
			information.setApplyTime(new Date());
			result = informationMapper.insert(information);
		} else {
			information.setApplyTime(new Date());
			result = informationMapper.updateById(information);
		}
		return CommonUtils.msg(result);
	}
	
	@Override
	public SimpleResponse verify(String id, int state) {
		String userId = SecurityContext.getUserId();
		Information information = informationMapper.selectById(id);
		information.setId(id);
		information.setVerifyUser(userId);
		information.setVerifyTime(new Date());
		information.setState(state);
		if(state == Information.State.success.value) {
			information.setPublishTime(new Date());
		}
		//审核成功，修改资讯信息状态
		int result = informationMapper.verify(information);
		//如果都成功，将资讯信息推送关注粉丝
		if(state == Information.State.success.value && result > 0) {
			String applyUser = information.getApplyUser();
			//获取粉丝集合
			Set<String> followers = redisTemplate.opsForSet().members(RedisKey.FOLLOWER_OPERATION_PREFIX + applyUser);
			followers.forEach(follower -> {
				//将发布的资讯放入关注者的消息队列中
				redisTemplate.opsForList().leftPush(RedisKey.INFORMATION_ATTENTION_PREFIX + follower, id);
			});
		}
		return CommonUtils.msg(result);
	}
	
	@Override
	public SimpleResponse deleteById(String id) {
		int result = informationMapper.deleteById(id);
		return CommonUtils.msg(result);
	}
	
	@Override
	public SimpleResponse giveOrCancelGood(@PathVariable String id) {
		long result = 0;
		String userId = SecurityContext.getUserId();
		String key = RedisKey.INFORMATION_IS_GOOD_OPERATION_PRFIX + id;
		//判断是否点赞
		if(!redisTemplate.opsForSet().isMember(key, userId)) {
			//点赞
			result = redisTemplate.opsForSet().add(key, userId);
		} else {
			//取消点赞
			result = redisTemplate.opsForSet().remove(key, userId);
		};
		return CommonUtils.msg(result);
	}
	
	@Override
	public SimpleResponse isGood(String id) {
		String userId = SecurityContext.getUserId();
		String key = RedisKey.INFORMATION_IS_GOOD_OPERATION_PRFIX + id;
		Boolean exist = redisTemplate.opsForSet().isMember(key, userId);
		return SimpleResponse.success().put("data", exist);
	};
	
	private String getImageUrlFromText(String content) {
		Matcher matcher = ATTR_PATTERN.matcher(content);
		  String images = "";
		   while (matcher.find()) {
			   images += matcher.group(1)+",";
		   }
		return images;
	}

}
